import 'package:bilibili/basic/model/video_model.dart';
import 'package:bilibili/basic/navigator/hi_navigator.dart';
import 'package:bilibili/basic/page/login_page.dart';
import 'package:bilibili/basic/page/register_page.dart';
import 'package:bilibili/basic/page/video_detail_page.dart';
import 'package:bilibili/basic/util/toast.dart';
import 'package:flutter/material.dart';
import 'basic/db/hi_cache.dart';
import 'basic/http/dao/login_dao.dart';
import 'basic/page/home_page.dart';
import 'package:bilibili/basic/util/ui_config.dart' as MyColors;


void main() {
  runApp(const BiliApp());
}

class BiliApp extends StatefulWidget {
  const BiliApp({Key? key}) : super(key: key);
  @override
  _BiliAppState createState() => _BiliAppState();
}

class _BiliAppState extends State<BiliApp> {
  BiliRouterDelegate _routerDelegate = BiliRouterDelegate();
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<HiCache>(
      //初始化
      future: HiCache.preInit(),
      builder: (BuildContext context, AsyncSnapshot<HiCache> sanpshot) {
      var widget = sanpshot.connectionState == ConnectionState.done ?
      Router(
        routerDelegate: _routerDelegate,
      ) :
      const Scaffold(
       body: Center(
         child: CircularProgressIndicator(),
       ),
      );
      return MaterialApp(
        home: widget,
        theme: ThemeData(primarySwatch: MyColors.white),
      );
    });
  }
}




///定义数据路由，path
class BiliRoutePath {
  final String location;
  BiliRoutePath.home() : location = '/';
  BiliRoutePath.detail() : location = '/detail';
}

class BiliRouterDelegate extends RouterDelegate<BiliRoutePath> with ChangeNotifier,
    PopNavigatorRouterDelegateMixin<BiliRoutePath> {

  final GlobalKey<NavigatorState> navigatorKey;
  BiliRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>();
  List<MaterialPage>pages = [];
  VideoModel? videoModel;
  RouteStatus _routeStatus = RouteStatus.home;

  @override
  Widget build(BuildContext context) {
    var index = getPageIndex(pages, routeStatus);
    List<MaterialPage> tempPages = pages;
    if (index != -1) {
      tempPages = tempPages.sublist(0, index);
    }
    var page;
    if (routeStatus == RouteStatus.home) {
      pages.clear();
      page = pageWrap(HomePage(onJumpToDetail: (viewModel) {
        this.videoModel = videoModel;
        notifyListeners();
      }));
    } else if (routeStatus == RouteStatus.detail) {
      page = pageWrap(VideoDetailPage(videoModel!));
    } else if (routeStatus == RouteStatus.registration) {
      page = pageWrap(RegisterPage(onJumpToLogin: () {
       _routeStatus = RouteStatus.login;
       notifyListeners();
      }));
    } else if (routeStatus == RouteStatus.login) {
      page = pageWrap(LoginPage(onJumpRegistion: () {
        _routeStatus = RouteStatus.registration;
        notifyListeners();
      }, onSuccess: () {
        _routeStatus = RouteStatus.home;
        notifyListeners();
      }));
    }
    ///重新创建一个数组，否则pages因引用没有改变路由不会生效
    tempPages = [...tempPages, page];
    pages = tempPages;

    return WillPopScope(
      //fix Android物理返回键，无法返回上一页问题@https://github.com/flutter/flutter/issues/66349
      onWillPop: () async => !(await navigatorKey.currentState?.maybePop() ?? false),
      child: Navigator(
        key: navigatorKey,
        pages: pages,
        onPopPage: (route, result)  {
          //登录页未登录返回拦截
          if ((route.settings as MaterialPage).child is LoginPage) {
            if (!hasLogin) {
              showWarnToast('请先登录');
              return false;
            }
          }
          //执行返回操作
          if (!route.didPop(result)) {
            return false;
          }
          pages.removeLast();
          return true;
        },
      ));
  }

  bool get hasLogin => LoginDao.getBoardingPass() != null;
  ///在这里对路由状态进行拦截
  RouteStatus get routeStatus {
    if (_routeStatus != RouteStatus.registration && !hasLogin) {
      return _routeStatus = RouteStatus.login;
    } else if (videoModel != null) {
      return _routeStatus = RouteStatus.detail;
    } else {
      return _routeStatus;
    }
  }

  @override
  Future<void> setNewRoutePath(BiliRoutePath path) async {}

}
